package my.netty.bootstrap;

import my.netty.channel.EventLoopGroup;
import my.netty.channel.ServerChannel;
import my.netty.channel.handler.ChannelInitializer;
import my.netty.exception.ChannelException;

import java.lang.reflect.Constructor;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

public class ServerBootstrap {

    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;

    private Class<? extends ServerChannel> serverChannelClass;
    private ServerChannel serverChannel;

    private ChannelInitializer childInitializer;

    public ServerBootstrap() {

    }

    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        this.bossGroup = parentGroup;
        this.workerGroup = childGroup;
        return this;
    }

    public ServerBootstrap channel(Class<? extends ServerChannel> serverChannelClass) {
        this.serverChannelClass = serverChannelClass;
        return this;
    }

    public ServerBootstrap childHandler(ChannelInitializer childInitializer) {
        this.childInitializer = childInitializer;
        return this;
    }

    public void bind(int port) {
        bind(new InetSocketAddress(port));
    }

    public void bind(String host, int inetPort) {
        bind(new InetSocketAddress(host, inetPort));
    }

    public void bind(SocketAddress localAddress) {
        try {
            Constructor<? extends ServerChannel> constructor = serverChannelClass.getConstructor(EventLoopGroup.class, ChannelInitializer.class);
            this.serverChannel = constructor.newInstance(workerGroup, childInitializer);
        } catch (Throwable e) {
            throw new ChannelException("init channel", e);
        }
        bossGroup.register(serverChannel);
        doBind(localAddress);
    }

    private void doBind(SocketAddress localAddress) {
        serverChannel.bind(localAddress);
    }
}
